package com.zh.config;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zh.user.entity.SysUser;
import com.zh.user.service.SysPermissionService;
import com.zh.user.service.SysRoleService;
import com.zh.user.service.SysUserService;
import com.zh.utils.JwtToken;
import com.zh.utils.JwtUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

/**
 * @Description: 继承AuthorizingRealm
 * @ClassName MyRealm
 * @date: 2021.04.09 16:37
 * @Author: zhanghang
 */
public class MyRealm extends AuthorizingRealm {
    @Autowired
    SysUserService sysUserService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysPermissionService sysPermissionService;
    /**
     * 授权
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        System.out.println("执行了==》》授权doGetAuthorizationInfo");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        SysUser user = (SysUser) principalCollection.getPrimaryPrincipal();
        // 查询当前用户的角色
        //赋予用户角色
        List<String> roleByUsername = sysRoleService.getRoleByUsername(user.getUsername());
        Set<String> roleSet = new HashSet<String>(roleByUsername);
        //赋予用户权限
        Set<String> permissionSSet = sysPermissionService.getPermissionServiceByUsername(user.getUsername());

        info.setRoles(roleSet);
        info.setStringPermissions(permissionSSet);
        return info;
    }
    /**
     * 认证
     *
     * @param
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken auth) throws AuthenticationException {
        System.out.println("执行了==》》doGetAuthenticationInfo");
//        UsernamePasswordToken userToken = (UsernamePasswordToken) token;
//        String username = ((UsernamePasswordToken) token).getUsername();
//        //用户名，密码，数据库中取
//        SysUser user = sysUserService.getOne(new QueryWrapper<SysUser>().lambda().eq(SysUser::getUsername, userToken.getUsername()));
//        if (null == user) {
//            return null;//抛出异常UnknownAccountException
//        }

        String token = Optional.ofNullable(auth.getCredentials()).map(to -> to.toString()).orElse(null);
        if (StrUtil.isEmpty(token)){
            System.out.println("没有传入token");
            return null;
        }
        // 解析token
        String username = JwtUtil.getUsername(token);
        if (StrUtil.isEmpty(username)){
            System.out.println("该token为无效数据");
            return null;
        }
        if (!JwtUtil.verify(token,username)){
            System.out.println("认证失败");
            return null;
        }
        SysUser sysUser = new SysUser();
        sysUser.setUsername(username);
        return new SimpleAuthenticationInfo(sysUser,token, getName());

        //密码认证shiro做
        /**
         * 参数说明：
         * 1. user： 这里可以传入user对象，也可以传入账号。
         *      对应的就是这里传入的是什么，在上面授权方法里principalCollection.getPrimaryPrincipal()就只能强转成什么
         * 2. hashedCredentials: 数据库中的密码
         * 3. credentialsSalt： 盐值
         * 4. realmName： 当前realm的名称
         */
//        return new SimpleAuthenticationInfo(user, user.getPassword(),  ByteSource.Util.bytes(user.getUsername()),getName());
    }

    // 限定这个Realm只支持我们自定义的JWT Token
    // 想要使用token 必须重写这个方法，要判断AuthenticationToken 的类型为我们自定义的JwtToken
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }


}
